import { Request, Response } from "express";
import prisma from "../lib/prisma";
import { verifyPassword, hashPassword } from "../utils/auth";
import { generateToken } from "../utils/jwt";
import svgCaptcha from "svg-captcha";
import { UserService } from "../services/userService";

const userService = new UserService();

// 内存存储验证码（生产环境建议使用Redis）
const captchaStore = new Map<string, { code: string; expiry: number }>();

// 内存存储登录失败次数（生产环境建议使用Redis）
const loginFailureStore = new Map<string, { count: number; lastAttempt: number; lockUntil?: number }>();

// 登录失败限制配置
const LOGIN_FAILURE_CONFIG = {
  maxAttempts: 10, // 最大尝试次数
  lockDuration: 30 * 60 * 1000, // 锁定时长（30分钟）
  resetWindow: 15 * 60 * 1000, // 重置窗口（15分钟）
};

// 获取客户端IP地址
const getClientIP = (req: Request): string => {
  return (req.headers["x-forwarded-for"] as string)?.split(",")[0] || req.connection.remoteAddress || req.socket.remoteAddress || "unknown";
};

// 检查IP是否被锁定
const isIPLocked = (ip: string): boolean => {
  const record = loginFailureStore.get(ip);
  if (!record) return false;

  const now = Date.now();

  // 如果有锁定时间且还在锁定期内
  if (record.lockUntil && record.lockUntil > now) {
    return true;
  }

  // 如果锁定时间已过，清除记录
  if (record.lockUntil && record.lockUntil <= now) {
    loginFailureStore.delete(ip);
    return false;
  }

  return false;
};

// 记录登录失败
const recordLoginFailure = (ip: string): void => {
  const now = Date.now();
  const record = loginFailureStore.get(ip);

  if (!record) {
    // 首次失败
    loginFailureStore.set(ip, {
      count: 1,
      lastAttempt: now,
    });
  } else {
    // 如果距离上次尝试超过重置窗口，重置计数
    if (now - record.lastAttempt > LOGIN_FAILURE_CONFIG.resetWindow) {
      loginFailureStore.set(ip, {
        count: 1,
        lastAttempt: now,
      });
    } else {
      // 增加失败次数
      const newCount = record.count + 1;
      const updateRecord = {
        count: newCount,
        lastAttempt: now,
        lockUntil: undefined as number | undefined,
      };

      // 如果达到最大尝试次数，锁定IP
      if (newCount >= LOGIN_FAILURE_CONFIG.maxAttempts) {
        updateRecord.lockUntil = now + LOGIN_FAILURE_CONFIG.lockDuration;
      }

      loginFailureStore.set(ip, updateRecord);
    }
  }
};

// 清除登录失败记录
const clearLoginFailure = (ip: string): void => {
  loginFailureStore.delete(ip);
};

// 获取剩余锁定时间
const getRemainingLockTime = (ip: string): number => {
  const record = loginFailureStore.get(ip);
  if (!record || !record.lockUntil) return 0;

  const remaining = record.lockUntil - Date.now();
  return Math.max(0, Math.ceil(remaining / 1000 / 60)); // 返回分钟数
};

// 获取验证码
export const getCaptcha = async (req: Request, res: Response) => {
  try {
    const captchaId = Date.now().toString() + Math.random().toString(36).substr(2, 9);

    // 使用svg-captcha生成验证码
    const captcha = svgCaptcha.create({
      size: 4, // 验证码长度
      ignoreChars: "0o1ilI", // 忽略容易混淆的字符
      noise: 2, // 干扰线数量
      color: true, // 使用彩色
      background: "#f8f9fa", // 背景色
      width: 120,
      height: 40,
      fontSize: 50,
    });

    const expiry = Date.now() + 5 * 60 * 1000; // 5分钟过期

    // 存储验证码
    captchaStore.set(captchaId, { code: captcha.text, expiry });

    // 清理过期的验证码
    for (const [key, value] of captchaStore.entries()) {
      if (value.expiry < Date.now()) {
        captchaStore.delete(key);
      }
    }

    res.json({
      success: true,
      captchaId,
      captchaSvg: captcha.data,
    });
  } catch (error) {
    console.error("生成验证码失败:", error);
    res.status(500).json({ success: false, message: "生成验证码失败" });
  }
};

// 验证验证码
const verifyCaptcha = (captchaId: string, userCode: string): boolean => {
  const stored = captchaStore.get(captchaId);
  if (!stored) {
    return false;
  }

  if (stored.expiry < Date.now()) {
    captchaStore.delete(captchaId);
    return false;
  }

  const isValid = stored.code.toLowerCase() === userCode.toLowerCase();
  if (isValid) {
    captchaStore.delete(captchaId); // 验证后立即删除
  }

  return isValid;
};

// 获取登录状态（检查IP是否被锁定）
export const getLoginStatus = async (req: Request, res: Response) => {
  try {
    const clientIP = getClientIP(req);
    const record = loginFailureStore.get(clientIP);

    if (isIPLocked(clientIP)) {
      const remainingTime = getRemainingLockTime(clientIP);
      return res.json({
        success: true,
        data: {
          isLocked: true,
          remainingTime,
          failureCount: record?.count || 0,
          maxAttempts: LOGIN_FAILURE_CONFIG.maxAttempts,
        },
      });
    }

    return res.json({
      success: true,
      data: {
        isLocked: false,
        remainingTime: 0,
        failureCount: record?.count || 0,
        maxAttempts: LOGIN_FAILURE_CONFIG.maxAttempts,
      },
    });
  } catch (error) {
    console.error("获取登录状态失败:", error);
    res.status(500).json({ success: false, message: "获取登录状态失败" });
  }
};

// 管理员注册
export const registerAdmin = async (req: Request, res: Response) => {
  try {
    const { username, email, password } = req.body;
    if (!username || !password) {
      return res.status(400).json({ success: false, message: "用户名和密码不能为空" });
    }
    // 检查用户名或邮箱是否已存在
    const exist = await prisma.user.findFirst({
      where: {
        OR: [{ username }, { email: email || "" }],
      },
    });
    if (exist) {
      return res.status(400).json({ success: false, message: "用户名或邮箱已存在" });
    }
    const hashed = await hashPassword(password);
    const user = await prisma.user.create({
      data: {
        username,
        email,
        password: hashed,
      },
    });
    res.json({ success: true, message: "管理员账号创建成功", admin: { id: user.id, username: user.username, email: user.email } });
  } catch (error) {
    console.error("管理员注册失败:", error);
    res.status(500).json({ success: false, message: "服务器错误", error });
  }
};

// 基于 admin_user 表的登录
export const adminLogin = async (req: Request, res: Response) => {
  try {
    const { username, password, captchaId, captchaCode } = req.body;
    const clientIP = getClientIP(req);
    const isDevelopment = process.env.NODE_ENV === 'development';

    // 检查IP是否被锁定（开发环境跳过）
    if (!isDevelopment && isIPLocked(clientIP)) {
      const remainingTime = getRemainingLockTime(clientIP);
      return res.status(429).json({
        success: false,
        message: `登录尝试次数过多，请在${remainingTime}分钟后再试`,
      });
    }

    if (!username || !password) {
      return res.status(400).json({ success: false, message: "账号和密码不能为空" });
    }

    if (!captchaId || !captchaCode) {
      return res.status(400).json({ success: false, message: "请输入验证码" });
    }

    // 验证验证码（开发环境跳过验证码检查）
    if (!isDevelopment && !verifyCaptcha(captchaId, captchaCode)) {
      recordLoginFailure(clientIP); // 记录失败
      return res.status(400).json({ success: false, message: "验证码错误或已过期" });
    }

    // 支持用户名或邮箱登录
    const user = await userService.getUserByUsername(username);

    if (!user) {
      if (!isDevelopment) recordLoginFailure(clientIP); // 开发环境不记录失败
      return res.status(200).json({ success: false, message: "账号不存在或已禁用" });
    }

    const isValid = await verifyPassword(password, user.password);
    if (!isValid) {
      if (!isDevelopment) recordLoginFailure(clientIP); // 开发环境不记录失败
      return res.status(200).json({ success: false, message: "密码错误" });
    }

    // 登录成功，清除失败记录（开发环境跳过）
    if (!isDevelopment) clearLoginFailure(clientIP);

    // 更新最后登录时间
    await userService.updateLastLogin(user.id);

    // 生成JWT
    const token = generateToken({
      id: user.id,
      username: user.username,
      email: user.email || "",
      roles: [user.role],
      businessLine: "",
    });

    console.log(username + "：登录成功");
    // 动态设置cookie属性，兼容http和https
    const isHttps = process.env.HTTPS === "true";

    // 获取域名配置，支持www和非www域名共享cookie
    const cookieDomain = process.env.COOKIE_DOMAIN || undefined;

    res.cookie("token", token, {
      httpOnly: true,
      secure: isHttps, // https时为true，http时为false
      sameSite: isHttps ? "none" : "lax", // https时为'none'，http时为'lax'
      maxAge: 30 * 24 * 60 * 60 * 1000, // 30天
      path: "/",
      domain: cookieDomain, // 设置域名，支持子域名共享
    });
    res.status(200).json({
      success: true,
      message: "登录成功",
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        roles: [user.role],
      },
    });
  } catch (error) {
    console.error("管理员登录失败:", error);
    res.status(500).json({ success: false, message: "服务器错误", error });
  }
};

// 管理员退出
export const adminLogout = (req: Request, res: Response) => {
  try {
    // 通过设置一个过去的过期时间来清除cookie
    const isHttps = process.env.HTTPS === "true";
    res.cookie("token", "", {
      httpOnly: true,
      secure: isHttps,
      sameSite: isHttps ? "none" : "lax",
      expires: new Date(0),
      path: "/",
    });
    return res.status(200).json({ success: true, message: "退出成功" });
  } catch (error) {
    console.error("管理员退出失败:", error);
    res.status(500).json({ success: false, message: "服务器错误" });
  }
};
